﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Windows.Forms;
using GauSmart.core;
using SharpMap.Data.Providers;
using System.IO;

namespace GauSmart
{
    public partial class MainForm : Form
    {
        private List<Criteria> _criterias;
        private ShapeFile _potentialShape;
        private List<ShapeFile> _criteriaShapeList;
        private Engine _engine;
        private WeightForm _weightForm;
        private bool _hasWeight;

        public MainForm()
        {
            InitializeComponent();
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            /* maybe needed */
        }

        private void saveResultToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (_engine.HasResult)
            {
                if (saveFileDialogResultShape.ShowDialog() == DialogResult.OK)
                {
                    _engine.ExtractResultMap(Path.GetDirectoryName(saveFileDialogResultShape.FileName),
                        Path.GetFileNameWithoutExtension(saveFileDialogResultShape.FileName));
                }
            }
            else
            {
                MessageBox.Show("There is no result map to save.", "Error",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void saveAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (_engine.HasResult)
            {
                if (saveFileDialogResultShape.ShowDialog() == DialogResult.OK)
                {
                    _engine.ExtractSuitabilityMaps(Path.GetDirectoryName(saveFileDialogResultShape.FileName));
                }
            }
            else
            {
                MessageBox.Show("There is no result map to save.", "Error",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void LoadCriteriaToolStripMenuItemClick(object sender, EventArgs e)
        {
            if (openFileDialogCriteriasXml.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    _criterias = Helpers.GetCriteriaList(openFileDialogCriteriasXml.FileName);

                    foreach (Criteria criteria in _criterias)
                    {
                        int tncc = 0;
                        TreeNode[] tncriteria = new TreeNode[criteria.suitabilities.Count];
                        foreach (Suitability suitability in criteria.suitabilities)
                        {
                            int tnrc = 0;
                            TreeNode[] tnranges = new TreeNode[suitability.ranges.Length];
                            foreach (Range ranges in suitability.ranges)
                            {
                                tnranges[tnrc] = new TreeNode(ranges.suitability.ToString() + " -> " +
                                                              ranges.start.ToString(CultureInfo.InvariantCulture));
                                tnrc++;
                            }
                            tncriteria[tncc] = new TreeNode(suitability.name, tnranges);
                            tncc++;
                        }
                        treeViewCriterias.Nodes.Add(new TreeNode(criteria.type.ToString() + " : " +
                                                                 criteria.name, tncriteria));
                    }

                    listBoxStatusLog.Items.Add("Criterias have been loaded.");
                    listBoxStatusLog.Items.Add("There are " + _criterias.Count + " criterias.");
                    listBoxStatusLog.Items.Add("You can start to load criteria shape files.");
                    statusLabel.Text = "Load " + _criterias.Count + " criteria shape files.";
                    shapeToolStripMenuItem.Enabled = true;
                    criteriaToolStripMenuItem.Enabled = false;
                }
                catch(Exception ex)
                {
                    MessageBox.Show(ex.Message, "Error",
                        MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private void LoadCriteriaShapeFilesToolStripMenuItemClick(object sender, EventArgs e)
        {
            _criteriaShapeList = new List<ShapeFile>();
            foreach (Criteria criteria in _criterias)
            {
                if (criteria.type.Equals(CriteriaType.NDVI) || criteria.type.Equals(CriteriaType.SLOPE))
                    break;
                statusLabel.Text = "Load " + criteria.name + " shape file.";

                DialogResult dialogResult = openFileDialogCriteriaShapes.ShowDialog();

                if (dialogResult == DialogResult.OK)
                {
                    _criteriaShapeList.Add(new ShapeFile(openFileDialogCriteriaShapes.FileName, true));

                    listBoxStatusLog.Items.Add("Criteria shape file "
                        + openFileDialogCriteriaShapes.FileName + " has been loaded.");
                }
                else if (dialogResult == DialogResult.Cancel)
                {
                    _criteriaShapeList.Clear();
                    break;
                }
                listBoxStatusLog.Items.Add(
                    "Loading has been done for criteria shape files. You can now add potential shape file.");
                statusLabel.Text = "Load potential shape file.";
                loadPotentialShapeFileToolStripMenuItem.Enabled = true;
                loadCriteriaShapeFilesToolStripMenuItem.Enabled = false;
            }
        }

        private void LoadPotentialShapeFileToolStripMenuItemClick(object sender, EventArgs e)
        {
            if (openFileDialogPotentialShape.ShowDialog() == DialogResult.OK)
            {
                _potentialShape = new ShapeFile(
                    openFileDialogPotentialShape.FileName, true);

                if (Helpers.IsPotentialShape(_potentialShape))
                {
                    listBoxStatusLog.Items.Add("Potential shape file " +
                                               openFileDialogPotentialShape.FileName + " has been loaded.");
                    statusLabel.Text = "Determine weights.";
                    loadPotentialShapeFileToolStripMenuItem.Enabled = false;
                    shapeToolStripMenuItem.Enabled = false;
                    weightToolStripMenuItem.Enabled = true;
                }
                else
                {
                    MessageBox.Show("Invalid potential file", "Error",
                        MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private void weightToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (_hasWeight)
            {
                _weightForm.Show();
            }
            else
            {
                _weightForm = new WeightForm(_criterias[0]);
                _weightForm.Show();
                _weightForm.VisibleChanged += _weightForm_VisibleChanged;
            }
        }

        private void _weightForm_VisibleChanged(object sender, EventArgs e)
        {
            _hasWeight = true;
            listBoxStatusLog.Items.Add("You can evaluate the suitabilaty map.");
            statusLabel.Text = "Ready to evaluate";
            if (!buttonEvaluate.Enabled)
            {
                buttonEvaluate.Enabled = true;
            }
        }

        private void buttonEvaluate_Click(object sender, EventArgs e)
        {
            if(_engine == null)
            {
                buttonEvaluate.Enabled = false;

                DistanceType distanceType = DistanceType.POLYGON;

                if (radioButtonPolygonDistance.Checked)
                {
                    distanceType = DistanceType.POLYGON;
                }
                else if (radioButtonCentroidDistance.Checked)
                {
                    distanceType = DistanceType.CENTROID;
                }
                else if (radioButtonBoundingBoxDistance.Checked)
                {
                    distanceType = DistanceType.BOUNDINGBOX;
                }

                _engine = new Engine(_criterias, _criteriaShapeList, _potentialShape, distanceType);
                _engine.GetResultCompleted += Engine_GetResultCompleted;
            }

            listBoxStatusLog.Items.Add("Evaluation has been started at " + DateTime.Now.ToString());
            statusLabel.Text = "Evaluation is in progress";

            _engine.GetResultAsync(_weightForm.WeightList);

            toolStripProgressBarEvaluation.Style = ProgressBarStyle.Marquee;
            toolStripProgressBarEvaluation.MarqueeAnimationSpeed = 30;
        }

        private void Engine_GetResultCompleted(object sender, GetResultAsyncCompletedEventArgs args)
        {
            toolStripProgressBarEvaluation.Style = ProgressBarStyle.Continuous;
            toolStripProgressBarEvaluation.MarqueeAnimationSpeed = 0;
            MessageBox.Show("Evaluation has been done at " + args.Now.ToString(),
                "Done", MessageBoxButtons.OK, MessageBoxIcon.Information);
            toolStripProgressBarEvaluation.Style = ProgressBarStyle.Blocks;
            listBoxStatusLog.Items.Add("Evaluation has been done at "+ args.Now.ToString());
            statusLabel.Text = "Done";
            buttonEvaluate.Enabled = true;
            saveResultToolStripMenuItem.Enabled = true;
            saveAllToolStripMenuItem.Enabled = true;
        }

        private void MainForm_SizeChanged(object sender, EventArgs e)
        {
        }
    }
}
